home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / akputil7.zoo / cp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-16  |  4.5 KB  |  197 lines

  1. #include <minimal.h>
  2. #include <osbind.h>
  3. #include <string.h>
  4.  
  5. #define TRUE 1
  6. #define FALSE 0
  7.  
  8. #define NULL 0
  9. #define FILENAME_MAX 128
  10.  
  11. extern char *syserr(long);
  12.  
  13. #define DIRSEP(c) (((c) == '\\') || ((c) == '/'))
  14.  
  15. int
  16. do_cp(char *src,char *dest,int destisdir) {
  17.     long size, rsize, wsize;
  18.     int srcfd = 0, destfd = 0;
  19.     char *buf = NULL;
  20.     long bsize;
  21.     char *e, *efile;
  22.     long err;
  23.     char attr;
  24.     int datime[2];
  25.     char destname[FILENAME_MAX], *d;
  26.     char *s, *srcname;
  27.     int firstflag;
  28.  
  29.     /*
  30.      * if the dest is a directory:
  31.      *    put a backslash on the end if there isn't one there already,
  32.      *  set srcname past the last path separator in src (or src itself),
  33.      *    copy the last component of src after the trailing backslash,
  34.      *    set dest to this constructed filename.
  35.      */
  36.  
  37.     if (destisdir) {
  38.     strcpy(destname,dest);
  39.     for (d = destname; *d; d++) ;
  40.     if (!DIRSEP(*(d-1))) *d++ = '\\';
  41.     for (srcname = s = src; *s; s++) {
  42.         if (DIRSEP(*s)) srcname = s+1;
  43.     }
  44.     strcpy(d,srcname);
  45.     dest = destname;
  46.     }
  47.  
  48.     efile = src;
  49.     if ((err = srcfd = Fopen(src,0)) < 0) goto error;
  50.     if ((err = attr = Fattrib(src,0,0)) < 0) goto error;
  51.     if ((err = size = Fseek(0L,srcfd,2)) < 0) goto error;
  52.     if (err = Fseek(0L,srcfd,0)) goto error;
  53.     if (err = Fdatime(datime,srcfd,0)) goto error;
  54.  
  55.     bsize = size;
  56.     do {
  57.     if (buf = (char *)Malloc(bsize)) break;
  58.     bsize /= 2;
  59.     } while (bsize >= 512);
  60.  
  61.     if (buf == NULL) {
  62.     e = "no memory";
  63.     goto error1;
  64.     }
  65.  
  66.     /* We play games with firstflag so the dest file isn't created     */
  67.     /* until the source file has been opened, the memory allocated, and    */
  68.     /* the first buffer-full has actually been read.            */
  69.  
  70.     firstflag = 1;
  71.     while (1) {
  72.     efile = src;
  73.  
  74.     if ((err = rsize = Fread(srcfd,bsize,buf)) < 0) goto error;
  75.  
  76.     efile = dest;
  77.  
  78.     if (firstflag) {
  79.         if ((err = destfd = Fcreate(dest,0)) < 0) goto error;
  80.         firstflag = 0;
  81.     }
  82.  
  83.     /* rsize == 0 if we're done. */
  84.     /* File might be empty so break after creating dest. */
  85.     if (rsize == 0) break;
  86.  
  87.     if ((err = wsize = Fwrite(destfd,rsize,buf)) < 0) goto error;
  88.     else if (wsize != rsize) {
  89.         e = "write error (disk full?)";
  90.         goto error1;
  91.     }
  92.     }
  93.  
  94.     efile = dest;
  95.     if (err = Fdatime(datime,destfd,1)) goto error;
  96.     if (err = Fclose(destfd)) goto error;
  97.     destfd = 0;
  98.     if ((err = Fattrib(dest,1,attr)) < 0) goto error;
  99.     efile = src;
  100.     if (err = Fclose(srcfd)) goto error;
  101.     srcfd = 0;
  102.  
  103.     (void)Mfree(buf);
  104.     return 0;
  105.  
  106. error:
  107.     e = syserr(err);
  108. error1:
  109.     (void)Fwrite(2,(long)strlen(efile),efile);
  110.     (void)Fwrite(2,2L,": ");
  111.     (void)Fwrite(2,(long)strlen(e),e);
  112.     (void)Fwrite(2,2L,"\r\n");
  113.     if (srcfd) (void)Fclose(srcfd);
  114.     if (destfd) (void)Fclose(destfd);
  115.     if (buf) (void)Mfree(buf);
  116.     return 1;
  117. }
  118.  
  119. #define haswild(s) (strchr(s,'*') || strchr(s,'?'))
  120.  
  121. int
  122. main(int argc,char *argv[])
  123. {
  124.     char *p;
  125.     int e;
  126.     int destisdir;
  127.     char *s, *lastcomp;
  128.  
  129.     --argc, ++argv;
  130.     while (*argv && **argv == '-') {
  131.         p = &argv[0][1];
  132.         while (*p) {
  133.         switch (*p) {
  134.         case 'r': (void)Fwrite(2,23L,"cp -r not implemented\r\n");
  135.               exit(1);
  136.         default:
  137.             (void)Fwrite(2,16L,"Unknown option: ");
  138.             (void)Fwrite(2,1L,p);
  139.             (void)Fwrite(2,2L,"\r\n");
  140.             goto usage;
  141.         }
  142.         p++;
  143.     }
  144.     argc--, argv++;
  145.     }
  146.  
  147.     if (argc < 2) {
  148. usage:
  149.     (void)Fwrite(2,34L,"Usage: cp [-r] srcfiles ... dest\r\n");
  150.     Pterm(1);
  151.     }
  152.  
  153.     /* set p to point to the last arg; see if it's a directory */
  154.     p = argv[argc-1];
  155.     destisdir = 0;
  156.  
  157.     /* dest is a dir if the name is two letters long & ends with ':' */
  158.     if (*p && *(p+1) == ':' && !*(p+2)) {
  159.     destisdir = 1;
  160.     goto gotdir;
  161.     }
  162.  
  163.     for (lastcomp = s = p; *s; s++) {
  164.     if (DIRSEP(*s)) lastcomp = s+1;
  165.     }
  166.  
  167.     /* dot and dot-dot are directories (trust me), and if   */
  168.     /* the name ends with a DIRSEP it's a directory too.    */
  169.  
  170.     if (!*lastcomp || 
  171.     (*lastcomp == '.' && 
  172.         (*(lastcomp+1) == '.' || (*(lastcomp+1)) == '\0'))) {
  173.     destisdir = 1;
  174.     }
  175.     else if (!haswild(p) && (Fsfirst(p,-1) == 0)) {
  176.     destisdir = ((struct _dta *)Fgetdta())->dta_attribute & 0x10;
  177.     }
  178.  
  179. gotdir:
  180.     if (argc == 2) {
  181.     return do_cp(argv[0],argv[1],destisdir);
  182.     }
  183.  
  184.     if (!destisdir) {
  185.     (void)Fwrite(2,30L,"last arg must be a directory\r\n");
  186.     Pterm(1);
  187.     }
  188.  
  189.     e = 0;
  190.     while (argc > 1) {
  191.     e |= do_cp(*argv,p,1);
  192.     argv++, argc--;
  193.     }
  194.     return (e != 0);
  195. }
  196.  
  197.